{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "cFloNx163DCr"
      },
      "source": [
        "##### Copyright 2020 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "iSdwTGPc3Hpj"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BE2AKncl3QJZ"
      },
      "source": [
        "# TensorBoard の Embedding Projector でデータを視覚化する\n",
        "\n",
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "<img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\"><a>TensorFlow.org で表示</a>\n",
        "</td>\n",
        "  <td>\n",
        "<img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\"><a target=\"_blank\" href=\"https://github.com/tensorflow/docs-l10n/blob/master/site/ja/tensorboard/tensorboard_projector_plugin.ipynb\">Google Colab で実行</a>\n",
        "</td>\n",
        "  <td>\n",
        "<img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\"><a target=\"_blank\" href=\"https://github.com/tensorflow/tensorboard/blob/master/docs/tensorboard_projector_plugin.ipynb\">GitHub でソースを表示</a>\n",
        "</td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "v4s3Sf2I3mJr"
      },
      "source": [
        "## 概要\n",
        "\n",
        "**TensorBoard の Embedding Projector** を使用すると、高次元埋め込みをグラフィカルに表現することができます。Embedding レイヤーの視覚化、調査、および理解に役立てられます。\n",
        "\n",
        " <img src=\"https://github.com/tensorflow/docs/blob/master/site/en/tutorials/text/images/embedding.jpg?raw=%5C\" alt=\"Screenshot of the embedding projector\" class=\"\">\n",
        "\n",
        "このチュートリアルでは、この種のトレーニング済みのレイヤーを視覚化する方法を学習します。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6-0rhuaW9f2-"
      },
      "source": [
        "## セットアップ\n",
        "\n",
        "このチュートリアルでは、TensorBoard を使用して、映画レビューデータを分類するために生成された Embedding レイヤーを視覚化します。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "TjRkD3r3etuL"
      },
      "outputs": [],
      "source": [
        "try:\n",
        "  # %tensorflow_version only exists in Colab.\n",
        "  %tensorflow_version 2.x\n",
        "except Exception:\n",
        "  pass\n",
        "\n",
        "%load_ext tensorboard"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "mh22cCoM8t7e"
      },
      "outputs": [],
      "source": [
        "import os\n",
        "import tensorflow as tf\n",
        "import tensorflow_datasets as tfds\n",
        "from tensorboard.plugins import projector\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xlp6ZASQB5go"
      },
      "source": [
        "## IMDB データ\n",
        "\n",
        "IMDB が提供する、センチメント（肯定的/否定的）でラベル付けされた 25,000 件の映画レビューのデータセットを使用します。レビューは前処理済みであり、それぞれ単語インデックスのシーケンス（整数）としてエンコードされています。便宜上、単語はデータセット内の全体的な頻度によってインデックス付けされてるため、たとえば、整数「3」はデータ内で 3 番目に頻度の高い単語にエンコードされます。このため、「高頻度で使用される上位 10,000 個の単語のみを考慮し、高頻度で使用される上位 20 個を除去する」といったフィルタ操作を素早く行うことができます。\n",
        "\n",
        "慣例として、「0」は特定の単語を表しませんが、任意の不明な単語をエンコードするのに使用されます。チュートリアルの後の方で、この行を視覚化から取り除きます。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "s0Yiw05gIgqS"
      },
      "outputs": [],
      "source": [
        "(train_data, test_data), info = tfds.load(\n",
        "    \"imdb_reviews/subwords8k\",\n",
        "    split=(tfds.Split.TRAIN, tfds.Split.TEST),\n",
        "    with_info=True,\n",
        "    as_supervised=True,\n",
        ")\n",
        "encoder = info.features[\"text\"].encoder\n",
        "\n",
        "# shuffle and pad the data.\n",
        "train_batches = train_data.shuffle(1000).padded_batch(\n",
        "    10, padded_shapes=((None,), ())\n",
        ")\n",
        "test_batches = test_data.shuffle(1000).padded_batch(\n",
        "    10, padded_shapes=((None,), ())\n",
        ")\n",
        "train_batch, train_labels = next(iter(train_batches))\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RpvPVCwO7bDj"
      },
      "source": [
        "# Keras Embedding レイヤー\n",
        "\n",
        "[Keras Embedding レイヤー](https://keras.io/layers/embeddings/)は、語彙の各単語に対して埋め込みをトレーニングするために使用できます。各単語（またはこの場合はサブ単語）は、モデルがトレーニングする 16 次元のベクトル（または埋め込み）に関連付けられます。\n",
        "\n",
        "単語の埋め込みに関する詳細は、[このチュートリアル](https://www.tensorflow.org/tutorials/text/word_embeddings?hl=en)をご覧ください。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "Fgoq5haqw8Z5"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2500/2500 [==============================] - 13s 5ms/step - loss: 0.5330 - accuracy: 0.6769 - val_loss: 0.4043 - val_accuracy: 0.7800\n"
          ]
        }
      ],
      "source": [
        "# Create an embedding layer\n",
        "embedding_dim = 16\n",
        "embedding = tf.keras.layers.Embedding(encoder.vocab_size, embedding_dim)\n",
        "# Train this embedding as part of a keras model\n",
        "model = tf.keras.Sequential(\n",
        "    [\n",
        "        embedding, # The embedding layer should be the first layer in a model.\n",
        "        tf.keras.layers.GlobalAveragePooling1D(),\n",
        "        tf.keras.layers.Dense(16, activation=\"relu\"),\n",
        "        tf.keras.layers.Dense(1),\n",
        "    ]\n",
        ")\n",
        "\n",
        "# Compile model\n",
        "model.compile(\n",
        "    optimizer=\"adam\",\n",
        "    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),\n",
        "    metrics=[\"accuracy\"],\n",
        ")\n",
        "\n",
        "# Train model\n",
        "history = model.fit(\n",
        "    train_batches, epochs=1, validation_data=test_batches, validation_steps=20\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "s9HmC29hdMnH"
      },
      "source": [
        "## TensorBoard 用にデータを保存する\n",
        "\n",
        "TensorBoard は、tensorflow プロジェクトのテンソルとメタデータを指定された `log_dir` ディレクトリのログから読み取ります。このチュートリアルでは、`/logs/imdb-example/` を使用します。\n",
        "\n",
        "このデータを視覚化するため、メタデータとともにチェックポイントをそのディレクトリに保存し、どのレイヤーを視覚化するのかを理解します。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Pi8_SCYRdn9x"
      },
      "outputs": [],
      "source": [
        "# Set up a logs directory, so Tensorboard knows where to look for files\n",
        "log_dir='/logs/imdb-example/'\n",
        "if not os.path.exists(log_dir):\n",
        "    os.makedirs(log_dir)\n",
        "\n",
        "# Save Labels separately on a line-by-line manner.\n",
        "with open(os.path.join(log_dir, 'metadata.tsv'), \"w\") as f:\n",
        "  for subwords in encoder.subwords:\n",
        "    f.write(\"{}\\n\".format(subwords))\n",
        "  # Fill in the rest of the labels with \"unknown\"\n",
        "  for unknown in range(1, encoder.vocab_size - len(encoder.subwords)):\n",
        "    f.write(\"unknown #{}\\n\".format(unknown))\n",
        "\n",
        "\n",
        "# Save the weights we want to analyse as a variable. Note that the first\n",
        "# value represents any unknown word, which is not in the metadata, so\n",
        "# we will remove that value.\n",
        "weights = tf.Variable(model.layers[0].get_weights()[0][1:])\n",
        "# Create a checkpoint from embedding, the filename and key are\n",
        "# name of the tensor.\n",
        "checkpoint = tf.train.Checkpoint(embedding=weights)\n",
        "checkpoint.save(os.path.join(log_dir, \"embedding.ckpt\"))\n",
        "\n",
        "# Set up config\n",
        "config = projector.ProjectorConfig()\n",
        "embedding = config.embeddings.add()\n",
        "# The name of the tensor will be suffixed by `/.ATTRIBUTES/VARIABLE_VALUE`\n",
        "embedding.tensor_name = \"embedding/.ATTRIBUTES/VARIABLE_VALUE\"\n",
        "embedding.metadata_path = 'metadata.tsv'\n",
        "projector.visualize_embeddings(log_dir, config)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "PtL_KzYMBIzP"
      },
      "outputs": [],
      "source": [
        "%tensorboard --logdir /logs/imdb-example/"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YtzW8mr_wmbD"
      },
      "source": [
        "<img class=\"tfo-display-only-on-site\" src=\"images/embedding_projector.png?raw=1\">"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MG4hcUzQQoWA"
      },
      "source": [
        "## 分析\n",
        "\n",
        "TensorBoard Projector は、データを分析し、埋め込みの値を互いに比較して見ることのできる有用なツールです。ダッシュボードでは特定の語を検索でき、埋め込み空間内の近接する単語を強調表示することができます。この例からは、Wes **Anderson** と Alfred **Hitchcock** がともに中立した語であることがわかりますが、異なる文脈で参照されています。\n",
        "\n",
        "<img class=\"tfo-display-only-on-site\" src=\"images/embedding_projector_hitchcock.png?raw=1\">\n",
        "\n",
        "Hitchcock は `nightmare` などの単語により強く関連しており、同氏のホラー映画作品に関連している可能性があります。一方 Anderson は `heart` という単語により近く、同氏の心温まる作品スタイルを反映しています。\n",
        "\n",
        "<img class=\"tfo-display-only-on-site\" src=\"images/embedding_projector_anderson.png?raw=1\">"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "name": "tensorboard_projector_plugin.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
